package org.csource.quickstart.processor;


import java.util.LinkedList;
import java.util.Map;
import java.util.TreeMap;

import org.csource.quickstart.processor.group.AbstractChannelProcessor;
import org.csource.quickstart.util.AopTargetUtils;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;


public class FileProcessFactory
    implements
      FactoryBean<Object>,
      ApplicationListener<ContextRefreshedEvent>,
      DisposableBean {
  //
  private TreeMap<String,TreeMap<Integer, LinkedList<FileUploadProcessor>>> processorLogicDefination = Maps.newTreeMap();

  @Override
  public Object getObject() throws Exception {
    return processorLogicDefination;
  }

  @Override
  public Class<?> getObjectType() {
    return Object.class;
  }

  @Override
  public boolean isSingleton() {
    return true;
  }

  @Override
  public void onApplicationEvent(ContextRefreshedEvent event) {
    // Spring context initialized trigger
    if (event.getApplicationContext().getParent() == null) {
      loadProcessor(event);
    }

    // spring web root initialized trigger
    if (event.getApplicationContext().getDisplayName().equals("Root WebApplicationContext")) {
      if (processorLogicDefination.size()==0) {
        loadProcessor(event);
      }
    }
    
    System.out.println(JSON.toJSONString(processorLogicDefination,true));
  }

  /**
   * 处理所有处理器排序以及分组逻辑
   */
  private void loadProcessor(ContextRefreshedEvent event) {
    ApplicationContext ac = event.getApplicationContext();
    Map<String, FileUploadProcessor> beans = ac.getBeansOfType(FileUploadProcessor.class);
    if (beans != null && beans.size() > 0) {
      /**
       * 分组
       * public M -------
       * group1 1 ---
       *        2 ---
       *        3 ---
       * group2 1 ---
       *        2 ---
       *        3 ---        
       */
      
      for (Map.Entry<String, FileUploadProcessor> entry : beans.entrySet()) {
        
        FileUploadProcessor processor = entry.getValue();
        FileUploadProcessor target = null;//非代理的处理器
        
        
        try {
           target = (FileUploadProcessor) AopTargetUtils.getTarget(processor);
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
        
        ProcessorChannel processorGroup = target.getClass().getAnnotation(ProcessorChannel.class);
        
        String group = AbstractChannelProcessor.KEY;
        // 取出自定义分组
        if (processorGroup != null){
          group = processorGroup.channel();
        }else{
          //取出公共的注册链
          //默认就是公共分组了
        }
        TreeMap<Integer, LinkedList<FileUploadProcessor>> linkedTreeMap = processorLogicDefination.get(group);
        Integer orderIndex = Integer.MAX_VALUE;
        ProcessorOrder processorOrder = target.getClass().getAnnotation(ProcessorOrder.class);
        if (processorOrder != null) {
          orderIndex = processorOrder.order();
        }
        
        if (linkedTreeMap == null) {
          linkedTreeMap = new TreeMap<Integer, LinkedList<FileUploadProcessor>>();
          processorLogicDefination.put(group, linkedTreeMap);
        }
        
        LinkedList<FileUploadProcessor> storage = linkedTreeMap.get(orderIndex);
        if (storage == null) {
          storage = new LinkedList<FileUploadProcessor>();
          linkedTreeMap.put(orderIndex, storage);
        }
        storage.add(processor);
      }
      // linked

    }
  }

  @Override
  public void destroy() throws Exception {
    this.processorLogicDefination = null;
  }


}
